# coding=utf-8
import os
import logging
import logging.config
from flask import Flask
from config import BaseConfig
from flask.ext.cache import Cache

CONFIG_NAME_MAPPER = {
    'development': 'config.DevelopmentConfig',
    'testing': 'config.TestingConfig',
    'production': 'config.ProductionConfig',
    'local': 'config.LocalConfig',
}

from flask_apscheduler import APScheduler

scheduler = APScheduler()

cache = Cache()

app = None

from sqlalchemy.ext.declarative import DeclarativeMeta
from flask.json import JSONEncoder
from datetime import datetime


class CustomJSONEncoder(JSONEncoder):
    def default(self, obj):
        if isinstance(obj, datetime):
            return obj.strftime('%Y-%m-%d %H:%M:%S')
        elif isinstance(obj.__class__, DeclarativeMeta):
            return obj.to_dict()
        return super(CustomJSONEncoder, self).default(obj)


def create_app(flask_config = 'production', **kwargs):
    global app
    if app is None:
        app = Flask(__name__, **kwargs)
        app.json_encoder = CustomJSONEncoder

        config_name = os.getenv('FLASK_CONFIG', flask_config)
        app.config.from_object(CONFIG_NAME_MAPPER[config_name])

        app.config['socketio_app'] = None

        _log_config_file = '%s/logging.conf' % BaseConfig.PROJECT_ROOT

        logging.config.fileConfig(fname = _log_config_file)

        from . import extensions
        extensions.init_app(app)

        from . import modules
        modules.init_app(app)

        scheduler.init_app(app)
        scheduler.start()

        cache.init_app(app, config = BaseConfig.CACHE_CONFIG)

    return app
